﻿//////////////////////////////////////////////////////////////////////////////
//
// Copyright © 1998-2024 Glodon Company Limited.
//
// Licensed under the MIT License
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the “Software”),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//////////////////////////////////////////////////////////////////////////////
#include "GmMainWindow.h"
#include "IMainWndHelper.h"
#include "ApplicationWindowEvent.h"

// Ui框架相关
#include "GmSubFrame.h"
#include "IApplication.h"
#include "IApplicationConfig.h"
#include "IApplicationCloseStrategy.h"
#include "ISplashScreen.h"  // 启动画面
#include "StatusBarImpl.h"
#include "DockManagerImpl.h"
#include "IControlDefinitionLibrary.h"
#include "IRibbon.h"
#include "IUiManager.h"
#include "IUiDocument.h"
#include "MainWndHelperBase.h"
#include "MainWndProcessCommandUtil.h"  //控件命令  
#include "ApplyOrCancelWidget.h"

//////////////////////////////////////////////////////////////////////////
#include "IApplicationEvent.h"
#include "IApplicationWindowEvent.h"  
#include "PlatformUiRefreshedEvent.h"    
#include "PlatformUiRefreshedEventArgs.h" 


#include "ApplyOrCancelWidget.h"  //应用取消按钮
#include "UiNotificationUtils.h"  //弱提示
#include "FilePath.h"


#include "ThreeDimensionalSketchEditModeOption.h" /////// TODO:


#include <QApplication>
#include <QPainter>
#include <QTimer>
#include <QMdiArea>
#include <QPointF>
#include <QMenuBar>
#include <QtGui/QFontDatabase>

//////////////////////////////////////////////////////////////////////////
// 日志相关
#include "JournalUtils.h"
#include "GmJournalRecordEventReceiver.h"
#include "JournalUtils.h"
#include "GmJournalApplicationEventHandler.h"
//////////////////////////////////////////////////////////////////////////

// UiView模块
#include "IUiDocumentEvent.h"
#include "IUiDocumentViewManager.h"  
#include "IUiView.h"
#include "IUiEditModeManager.h"     /////// TODO:

// GcmpCommandAction模块
#include "IActionManager.h"

// 对外Command Id
#include "GcmpViewCommandNames.h"



// GcmpDevService 模块
#include "GbmpFileSystem.h"
#include "FilePathManager.h"

// data model
#include "IModelView.h"
#include "IElementBasicInformation.h"
#include "IDocumentManager.h"
#include "IDocument.h"
#include "IUiDocumentEventHandler.h"
#include "IUiDocumentEventArgs.h"
#include "ISelectionChangeEventHandler.h"
#include "ISelection.h"
#include "ISelectionChangeEvent.h"
#include "ISelectionChangeEventArgs.h"

#include "UiViewLayoutEvent.h"
#include "UiViewLayoutEventArgs.h"
#include "UiViewLayoutManager.h"

#include "GmUiNotificationFactory.h"
#include "GnufAsynchronousTaskManager.h"
#include <QTabBar>
#include "EnableCompileWarning_The_LAST_IncludeInCpp.h"

#define ID_PAGE_MODIFY                  L"gmModifyPage"


// 自定义窗口激活功能
#define ID_ACTIVE_MAIN_WINDOW WM_USER + 1001

using namespace gcmp;

bool IsSubFrameAutoClosed();

bool MainWindowAutoClosedFlag::m_bIsAutoClosed = false;

namespace
{
    class QtGmMdiArea : public QMdiArea
    {
    public:
        QtGmMdiArea(QWidget* pParent) : QMdiArea(pParent) {}

    private:
        void wheelEvent(QWheelEvent* pEvent) override
        {}
    };
}
namespace gcmp
{
    class GcmpUiDocumentEventHandler : public IUiDocumentEventHandler
    {
    public:
        GcmpUiDocumentEventHandler(GmMainWindow* pMainWindow)
            :m_pMainWindow(pMainWindow)
        {
            DBG_WARN_UNLESS(pMainWindow, L"pMainWindow为空",L"GDMPLab",L"2024-03-30");
        }

        ~GcmpUiDocumentEventHandler()
        {
        }

    public:
        virtual void On(IUiDocumentEventArgs* pArgs) override
        {
            DBG_WARN_AND_RETURN_VOID_UNLESS(pArgs, L"pArgs为空",L"GDMPLab",L"2024-03-30");
            DBG_WARN_AND_RETURN_VOID_UNLESS(this->m_pMainWindow, L"m_pMainWindow为空",L"GDMPLab",L"2024-03-30");

            UiDocumentEventType uiEventType = pArgs->GetType();
            switch (uiEventType)
            {
            case UiDocumentEventType::UiDocumentClosed:
            {
                std::vector<IUiDocument*> uiDocuments = IUiDocumentViewManager::Get()->GetAllUiDocuments();
                if (uiDocuments.empty())
                {
                    UiNotificationUtils::CloseNotificationMessages();
                }
                m_pMainWindow->DeleteApplyOrCancelGui(pArgs->GetUiDocument()->GetId());
                break;
            }
            case UiDocumentEventType::PreUpdateUiView:
            {
                IUiDocument* pUiDoc = pArgs->GetUiDocument();
                DBG_WARN_AND_RETURN_VOID_UNLESS(pUiDoc, L"pUiDoc为空",L"GDMPLab",L"2024-03-30");

                //////////////////////////////////////////////////////////////////////////
                // 避免出现ModelView被删除还强制刷新UiView问题
                IUiDocument* pCurrentUiDoc = IUiDocumentViewManager::Get()->GetCurrentUiDocument();
                if (pCurrentUiDoc == pUiDoc)
                {
                    IUiView* pCurrentUiView = IUiDocumentViewManager::Get()->GetCurrentUiView();
                    if (!pCurrentUiView || pCurrentUiView->GetModelView() == nullptr)
                    {
                        return;
                    }
                }
                //////////////////////////////////////////////////////////////////////////
                IUiManager* pUiMgr = IUiManager::Get();
                DBG_WARN_AND_RETURN_VOID_UNLESS(pUiMgr, L"pUiMgr为空！",L"GDMPLab",L"2024-03-30");
                pUiMgr->GetUiEditModeManager()->SyncUiEditMode(pUiDoc);
                break;
            }
            default: break;
            }
        }

    private:
        GmMainWindow* m_pMainWindow;
    };


    //////////////////////////////////////////////////////////////////////////
    class UIDocSelectionChangedEventHandler : public ISelectionChangeEventHandler
    {
    public:
        UIDocSelectionChangedEventHandler()
        {
        }

        ~UIDocSelectionChangedEventHandler()
        {
        }

        void On(ISelectionChangeEventArgs* pArgs) override
        {
            IUiDocumentViewManager *pUiDocManager = IUiDocumentViewManager::Get();
            DBG_WARN_AND_RETURN_VOID_UNLESS(pUiDocManager, L"pUiDocManager 为空！",L"GDMPLab",L"2024-03-30");
            IUiDocument *pUiDocument = pUiDocManager->GetCurrentUiDocument();
            if (pUiDocManager->GetCurrentUiDocument() && pUiDocument->GetDbDocument() != pArgs->GetDocument())
                return;

#ifndef EMSCRIPTEN
            IMainWindow::GetMainWindow()->UpdateControlStatus();
#endif
        }
    };

}

GmMainWindow::GmMainWindow()
    : QMainWindow()
    , m_pStatusBar(nullptr)
    , m_opJournalRecordEventReceiver(NEW_AS_OWNER_PTR(GmJournalRecordEventReceiver))
    , m_applicationIsClosing(false)
    , m_pGmJournalApplicationEventHandler(NEW_AS_OWNER_PTR(GmJournalApplicationEventHandler))
{
    setObjectName("RibbonMainWindow");
    m_opTrashBin = NEW_AS_OWNER_PTR(gcmp::TrashBin, this);
    m_asynchronousTaskManager = NEW_AS_OWNER_PTR(gnuf::AsynchronousTaskManager);
    m_pMainWindowHelper = NEW_AS_OWNER_PTR(MainWndHelperBase);
    m_pUiDocumentEventHandler = NEW_AS_OWNER_PTR(GcmpUiDocumentEventHandler, this);
    IUiManager* pUiMgr = IUiManager::Get();
    DBG_WARN_UNLESS(pUiMgr, L"pUiMgr为空！",L"GDMPLab",L"2024-03-30");
    pUiMgr->SetApplicationWindow(this);
    IUiDocumentViewManager *pUiDocumentViewMgr = IUiDocumentViewManager::Get();
    DBG_WARN_UNLESS(pUiDocumentViewMgr, L"pUiDocumentViewMgr为空！",L"GDMPLab",L"2024-03-30");
    gcmp::IUiDocumentEvent* pEvent = pUiDocumentViewMgr->GetUiDocumentEvent();
    DBG_WARN_UNLESS(pEvent, L"pEvent为空？",L"GDMPLab",L"2024-03-30");
    pEvent->Add(m_pUiDocumentEventHandler.get());

    m_opUIDocSelectionChangedEventHandler = NEW_AS_OWNER_PTR(UIDocSelectionChangedEventHandler);
    ISelection* pSelection = ISelection::Get();
    DBG_WARN_UNLESS(pSelection, L"pSelection为空？",L"GDMPLab",L"2024-03-30");
    ISelectionChangeEvent* pSelectEvent = pSelection->GetSelectionChangeEvent();
    DBG_WARN_UNLESS(pSelectEvent, L"pSelectEvent为空？",L"GDMPLab",L"2024-03-30");
    pSelectEvent->Add(m_opUIDocSelectionChangedEventHandler.get());

    // 设置风格。
    if (m_pRibbonBar || GetRibbon())
    {
        m_pRibbonBar->InitRibbonStyle();
    }

    // 设置Qt控件默认字体为"方正兰亭黑"
    std::string fontPath = StringUtil::ToString(FileSystem::GetExeDirPath() + L"Fonts/FZLTHJW.TTF");
    int id = QFontDatabase::addApplicationFont(fontPath.c_str());
    if (-1 != id)
    {
        const QString fml = QFontDatabase::applicationFontFamilies(id).at(0);
        QFont font = qApp->font();
        font.setFamily(fml);
        qApp->setFont(font);

        setFont(font);
        m_pRibbonBar->SetFont(font);
    }

    //// 设置主窗口等
    IApplication* pApplication = IApplication::Get();
    DBG_WARN_AND_RETURN_VOID_UNLESS(pApplication, L"pApplication为空？",L"GDMPLab",L"2024-03-30");
    std::vector<std::wstring> vecName= pApplication->GetCommandLineArgs();
    DBG_WARN_AND_RETURN_VOID_UNLESS(vecName.size() > 0, L"无命令行参数？",L"GDMPLab",L"2024-03-30");
    std::wstring fullName = vecName[0];
    FilePath filePath(fullName);
    std::wstring appName = filePath.GetFileNameWithoutExtension();
    ISplashScreen* pSplashScreen = pApplication->GetSplashScreen();
    if ((pSplashScreen) && (L"AppComponentEditor" != appName))
    {
        pSplashScreen->ShowMessage(GBMP_TR(L"正在初始化，请稍后..."));
        pSplashScreen->SetProgress(30);
        DBG_WARN_UNLESS(30 == pSplashScreen->GetProgress(), L"进度和设置的值不一致",L"GDMPLab",L"2024-03-30");
    }

    IUiManager* pUiManager = IUiManager::Get();
    DBG_WARN_AND_RETURN_VOID_UNLESS(pUiManager, L"pUiManager为空！",L"GDMPLab",L"2024-03-30");
    OwnerPtr<IDockManager> opDockManager = NEW_AS_OWNER_PTR(DockManagerImpl, const_cast<GmMainWindow*>(this));
    pUiManager->SetDockManager(TransferOwnership(opDockManager));

    // 初始化MDI区域。
    m_pMDIArea = NEW_AS_QT_CHILD(QtGmMdiArea, this);
    DBG_WARN_AND_RETURN_VOID_UNLESS(m_pMDIArea, L"m_pMDIArea为空！",L"GDMPLab",L"2024-03-30");
    m_pMDIArea->setBackground(QBrush(QColor(220, 220, 220))); // 底色
    m_pMDIArea->setLineWidth(3);
    m_pMDIArea->setFrameShape(QFrame::WinPanel);
    m_pMDIArea->setFrameShadow(QFrame::Sunken);
    m_pMDIArea->setViewMode(QMdiArea::SubWindowView);
    m_pMDIArea->setActivationOrder(QMdiArea::ActivationHistoryOrder);
    m_pMDIArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
    m_pMDIArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);

    setCentralWidget(m_pMDIArea);
    QObject::connect(m_pMDIArea, SIGNAL(subWindowActivated(QMdiSubWindow *)), this, SLOT(OnSubWindowActivated(QMdiSubWindow *)));
    // 关联弱提示
    GmUiNotificationFactory::GetInstance();
    pUiManager->SetUiNotificationParent(m_pMDIArea->winId());

    gcmp::JournalUtils::RegisterJournalRecordEventReceiver(m_opJournalRecordEventReceiver.get());


    m_pMainWindowEvent = NEW_AS_OWNER_PTR(ApplicationWindowEvent, L"MainWindowEvent", this);
    // 初始化几个单例。
    //////////////////////////////////////////////////////////////////////////

    // 设置停靠方式支持 Tab或者 上下分割
    setDockOptions(AllowNestedDocks| AllowTabbedDocks);
   
    // 配置三维草图编辑模式
    ThreeDimensionalSketchEditModeOption::SetModifyPageName(ID_PAGE_MODIFY);
    m_pPlatformUiRefreshedEvent = NEW_AS_OWNER_PTR(PlatformUiRefreshedEvent, L"PlatformUiRefreshedEvent", this);
    IApplication* application = IApplication::Get();
    DBG_WARN_AND_RETURN_VOID_UNLESS(application, L"application为空！",L"GDMPLab",L"2024-03-30");
    IApplicationEvent* pApplicationEvent = application->GetApplicationEvent();
    DBG_WARN_AND_RETURN_VOID_UNLESS(pApplicationEvent, L"pApplicationEvent为空！",L"GDMPLab",L"2024-03-30");
    pApplicationEvent->Add(m_pGmJournalApplicationEventHandler.get());
    m_opUiViewLayoutManager = NEW_AS_OWNER_PTR(UiViewLayoutManager);

    installEventFilter(this);
}

GmMainWindow::~GmMainWindow()
{
    // 置空弱提示父窗口
    IUiManager* pUiManager = IUiManager::Get();
    if (pUiManager != nullptr)
        pUiManager->SetUiNotificationParent(-1);

    //////////////////////////////////////////////////////////////////////////
    //关闭所有View！
    //原来采用m_pMDIArea->closeAllSubWindows()会导致独立的view关闭记录
    //现在采用程序关闭的方式，view关闭的过程中不会记录LOG
    closeAllSubWindowsAutomatically();
    disconnect(m_pMDIArea, SIGNAL(subWindowActivated(QMdiSubWindow *)), this, SLOT(OnSubWindowActivated(QMdiSubWindow *)));

    // 关闭所有的非UI文档，如族文档
    IDocumentManager::Get()->CloseAllDocuments();

    ApplicationWindowEvent* pMainWindowEvent = dynamic_cast<ApplicationWindowEvent*>(this->GetMainWindowEvent());
    DBG_WARN_UNLESS(pMainWindowEvent, L"主窗口对象析构时获取应用程序事件对象失败。",L"GDMPLab",L"2024-03-30");
    if (pMainWindowEvent)
    {
        ApplicationWindowEventArgs PreCloseEventArgs(ApplicationWindowEventType::PreClose);
        pMainWindowEvent->Emit(&PreCloseEventArgs);
    }

    gcmp::JournalUtils::UnregisterJournalRecordEventReceiver(m_opJournalRecordEventReceiver.get());
    gcmp::JournalUtils::RegisterJournalReplayEventReceiver(nullptr);
    gcmp::JournalUtils::RegisterJournalReplayNotficationReceiver(nullptr);

    if (pMainWindowEvent)
    {
        ApplicationWindowEventArgs ClosedEventArgs(ApplicationWindowEventType::Closed);
        pMainWindowEvent->Emit(&ClosedEventArgs);
    }
}

IControlDefinitionLibrary* GmMainWindow::GetControlDefinitionLibrary() const
{
    IUiManager* pUiMgr = IUiManager::Get();
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pUiMgr, L"pUiMgr为空！",L"GDMPLab",L"2024-03-30");
    return pUiMgr->GetControlDefinitionLibrary();
}

IRibbon* GmMainWindow::GetRibbon() const
{
    if (!m_pRibbonBar)
    {
        m_pRibbonBar = IRibbon::Create();
        GmMainWindow* self = const_cast<GmMainWindow*>(this);
        self->setMenuWidget(m_pRibbonBar->GetAsQMenuBar());
        m_pRibbonBar->SetFrameThemeEnabled(true);
    }
   
    return m_pRibbonBar.get();
}

UInt64 GmMainWindow::GetApplicationWindowId() const
{
    return this->winId();
}

bool GmMainWindow::SetWindowStyleTheme(WindowStyleTheme styleTheme)
{
    if (!m_pRibbonBar)
    {
        return false;
    }
    m_pRibbonBar->SetWindowStyleTheme(styleTheme);
    return true;
}

IStatusBar* GmMainWindow::GetStatusBar() const
{
    if (!m_pStatusBar)
    {
        GmMainWindow* pMainWindow = const_cast<GmMainWindow*>(this);
        m_pStatusBar = NEW_AS_QT_CHILD(StatusBarImpl, pMainWindow);
        pMainWindow->setStatusBar(m_pStatusBar);
    }
    return m_pStatusBar;
}

IApplicationWindowEvent* GmMainWindow::GetMainWindowEvent() const
{
    return const_cast<IApplicationWindowEvent*>(m_pMainWindowEvent.get());
}

void GmMainWindow::Show()
{
    QMainWindow::show();
}

void GmMainWindow::Hide()
{
    QMainWindow::hide();
}

void GmMainWindow::ShowMaximized()
{
    QMainWindow::showMaximized();
}

void GmMainWindow::ShowMinimized()
{
    QMainWindow::showMinimized();
}

void GmMainWindow::ShowFullScreen()
{
    QMainWindow::showFullScreen();
}

void GmMainWindow::ShowNormal()
{
    QMainWindow::showNormal();
}

std::wstring GmMainWindow::GetWindowTitle() const
{
    return windowTitle().toStdWString();
}

bool GmMainWindow::SetWindowTitle(const std::wstring& title)
{
    setWindowTitle(QString::fromStdWString(title));
    return true;
}

void gcmp::GmMainWindow::SetUiViewDisabled(const std::vector<IUiView*>& vecUiViews, bool bDisable)
{
    IUiDocumentViewManager* pUiDocViewMgr = IUiDocumentViewManager::Get();
    DBG_WARN_AND_RETURN_VOID_UNLESS(pUiDocViewMgr, L"pUiDocViewMgr为空",L"GDMPLab",L"2024-03-30");
    IUiView* pCurrentUiView = pUiDocViewMgr->GetCurrentUiView();
    DBG_WARN_AND_RETURN_VOID_UNLESS(pCurrentUiView, L"pCurrentUiView为空",L"GDMPLab",L"2024-03-30");

    DBG_WARN_AND_RETURN_VOID_UNLESS(m_pMDIArea, L"m_pMDIArea为空",L"GDMPLab",L"2024-03-30");
    QList<QTabBar*> tabBarList = m_pMDIArea->findChildren<QTabBar*>();
    DBG_WARN_AND_RETURN_VOID_UNLESS(!tabBarList.isEmpty(), L"tabBarList为空",L"GDMPLab",L"2024-03-30");
    QList<QMdiSubWindow*> subWindowList = m_pMDIArea->subWindowList();
    DBG_WARN_AND_RETURN_VOID_UNLESS(!subWindowList.isEmpty(), L"subWindowList为空",L"GDMPLab",L"2024-03-30");

    QMdiSubWindow* pSubWindow = nullptr;
    GmSubFrame* pSubFrame = nullptr;
    IUiView* pUiView = nullptr;

    for (int i = 0; i < subWindowList.size(); ++i)
    {
        pSubWindow = subWindowList[i];
        DBG_WARN_AND_CONTINUE_UNLESS(pSubWindow, L"pSubWindow为空",L"GDMPLab",L"2024-03-30");
        pSubFrame = dynamic_cast<GmSubFrame*>(pSubWindow);
        DBG_WARN_AND_CONTINUE_UNLESS(pSubFrame, L"pSubFrame为空",L"GDMPLab",L"2024-03-30");
        pUiView = pSubFrame->GetView();
        DBG_WARN_AND_CONTINUE_UNLESS(pUiView, L"pUiView为空",L"GDMPLab",L"2024-03-30");

        auto iter = std::find(std::begin(vecUiViews), std::end(vecUiViews), pUiView);
        if (iter != std::end(vecUiViews))
        {
            if (bDisable)
            {
                if ((*iter) != pCurrentUiView)
                {
                    pSubFrame->setDisabled(true);
                    tabBarList[0]->setTabEnabled(i, false);
                    m_disableUiViews.insert(pUiView);
                }
            }
            else
            {
                pSubFrame->setDisabled(false);
                tabBarList[0]->setTabEnabled(i, true);                
                auto iter = m_disableUiViews.find(pUiView);
                if (iter != std::end(m_disableUiViews))
                {
                    m_disableUiViews.erase(iter);
                }
            }
        }
    }
}

// 临时，在(Gbmp,Gmj)MainWindowEventHandler中调用
void GmMainWindow::BuildUi()
{
    IApplication* pApplication = IApplication::Get();
    DBG_WARN_AND_RETURN_VOID_UNLESS(pApplication, L"pApplication为空？",L"GDMPLab",L"2024-03-30");
    std::vector<std::wstring> vecName = pApplication->GetCommandLineArgs();
    DBG_WARN_AND_RETURN_VOID_UNLESS(vecName.size() > 0, L"无命令行参数？",L"GDMPLab",L"2024-03-30");
    std::wstring fullName = vecName[0];
    FilePath filePath(fullName);
    std::wstring appName = filePath.GetFileNameWithoutExtension();

    ISplashScreen* pSplashScreen = pApplication->GetSplashScreen();
    if ((pSplashScreen) && (L"AppComponentEditor" != appName))
    {
        pSplashScreen->ShowMessage(GBMP_TR(L"正在初始化面板，请稍后..."));
        pSplashScreen->SetProgress(70);
        DBG_WARN_UNLESS(70 == pSplashScreen->GetProgress(), L"进度和设置的值不一致",L"GDMPLab",L"2024-03-30");
    }

    //欢迎界面
   // GetUIWelcome()->Show();

    // 更新控件状态。
    UpdateControlStatus();
}

bool GmMainWindow::eventFilter(QObject *object, QEvent *event)
{
    if (event->type() == QEvent::Show && !m_disableUiViews.empty())
    {
        DBG_WARN_AND_RETURN_FALSE_UNLESS(m_pMDIArea, L"m_pMDIArea为空",L"GDMPLab",L"2024-03-30");
        QList<QTabBar*> tabBarList = m_pMDIArea->findChildren<QTabBar*>();
        DBG_WARN_AND_RETURN_FALSE_UNLESS(!tabBarList.isEmpty(), L"tabBarList为空",L"GDMPLab",L"2024-03-30");
        QList<QMdiSubWindow*> subWindowList = m_pMDIArea->subWindowList();
        DBG_WARN_AND_RETURN_FALSE_UNLESS(!subWindowList.isEmpty(), L"subWindowList为空",L"GDMPLab",L"2024-03-30");

        QMdiSubWindow* pSubWindow = nullptr;
        GmSubFrame* pSubFrame = nullptr;
        IUiView* pUiView = nullptr;

        for (int i = 0; i < subWindowList.size(); ++i)
        {
            pSubWindow = subWindowList[i];
            DBG_WARN_AND_CONTINUE_UNLESS(pSubWindow, L"pSubWindow为空",L"GDMPLab",L"2024-03-30");
            pSubFrame = dynamic_cast<GmSubFrame*>(pSubWindow);
            DBG_WARN_AND_CONTINUE_UNLESS(pSubFrame, L"pSubFrame为空",L"GDMPLab",L"2024-03-30");
            pUiView = pSubFrame->GetView();
            DBG_WARN_AND_CONTINUE_UNLESS(pUiView, L"pUiView为空",L"GDMPLab",L"2024-03-30");

            auto iter = m_disableUiViews.find(pUiView);
            if (iter != std::end(m_disableUiViews))
            {
                pSubFrame->setDisabled(true);
                tabBarList[0]->setTabEnabled(i, false);
            }
        }
    }
    return QMainWindow::eventFilter(object, event);
}

void GmMainWindow::keyPressEvent(QKeyEvent* pEvent)
{
    // 回放过程中不必理会用户输入
    if(gcmp::JournalUtils::IsInReplay())
        return;
    IUiDocumentViewManager* pUiDocumentViewManager = IUiDocumentViewManager::Get();
    DBG_WARN_AND_RETURN_VOID_UNLESS(pUiDocumentViewManager, L"pUiDocumentViewManager为空",L"GDMPLab",L"2024-03-30");

    IUiView* pUiView = pUiDocumentViewManager->GetCurrentUiView();
    if(pUiView)
    {
        QWidget* pViewWidget = QWidget::find((WId)pUiView->GetUiViewId());
        if(pViewWidget)
        {
            QObject* pObject = qobject_cast<QObject*>(pViewWidget);
            DBG_WARN_AND_RETURN_VOID_UNLESS( pObject, L"pObject 为空",L"GDMPLab",L"2024-03-30");
            pObject->event(pEvent);
            return ;
        }
    }
}

void GmMainWindow::closeEvent(QCloseEvent *event)
{
    //如果InteractivePicker命令还没有结束，需要先结束该命令再执行关闭命令
    if (!ProcessCommandUtil::IsLastCommandExecuted())
    {
        IActionManager::Reset();
        QApplication::postEvent(qApp, NEW_AS_QT(QCloseEvent, *event));
        event->ignore();
        return;
    }
    // 通知关闭程序，为所有Event Handlers发送事件
    IApplication::Get()->PreClose(!MainWindowAutoClosedFlag::IsAutoClosed());

    bool shouldExecuteBuiltInClose = true;

    // 如果有自定义关闭策略，执行自定义关闭策略。
    if (IApplicationCloseStrategy * pAppCloseStrategy = IApplication::Get()->GetCloseStrategy())
    {
        std::wstring errorMessage;
        if (pAppCloseStrategy->Close())
        {
            shouldExecuteBuiltInClose = pAppCloseStrategy->ShouldContinueBuiltInCloseAfterThisCloseWasCalled();
        }
        else
        {
            event->ignore();
            return;
        }
    }

    if (shouldExecuteBuiltInClose)
    {
        // 关闭主窗口前检查文档修改状态，并提示用户的确认(true表示可以继续关闭)
        //if (GmProcessReturnCode::RC_ERROR_FROM_JOURNAL_REPLAY != GmProcessReturnCode::GetReturnCode())
        if(!JournalUtils::IsReplayError())
        {
            bool statusOK = true;
            IUiDocumentViewManager* pUiDocumentViewManager = IUiDocumentViewManager::Get();
            DBG_WARN_AND_RETURN_VOID_UNLESS(pUiDocumentViewManager, L"pUiDocumentViewManager为空",L"GDMPLab",L"2024-03-30");

            std::vector<IUiDocument*> tempUIDocs = pUiDocumentViewManager->GetAllUiDocuments();
            while (!tempUIDocs.empty())
            {
                statusOK = statusOK && EnquiryDocumentBeforeClose(tempUIDocs.back());
                if (!statusOK)
                {
                    event->ignore();
                    return;
                }
                tempUIDocs.erase(tempUIDocs.end() - 1);
            }
        }
    }
    
    // 置空弱提示父窗口
    IUiManager* pUiMgr = IUiManager::Get();
    DBG_WARN_AND_RETURN_VOID_UNLESS(pUiMgr, L"pUiMgr为空！",L"GDMPLab",L"2024-03-30");
    pUiMgr->SetUiNotificationParent(-1);

    //////////////////////////////////////////////////////////////////////////
    //关闭所有View！
    //原来采用m_pMDIArea->closeAllSubWindows()会导致独立的view关闭记录
    //现在采用程序关闭的方式，view关闭的过程中不会记录LOG
    closeAllSubWindowsAutomatically();
    disconnect(m_pMDIArea, SIGNAL(subWindowActivated(QMdiSubWindow *)), this, SLOT(OnSubWindowActivated(QMdiSubWindow *)));

    // 关闭所有的非UI文档，如族文档
    IDocumentManager::Get()->CloseAllDocuments();
}

void GmMainWindow::moveEvent(QMoveEvent * pEvent)
{
    if (std::shared_ptr<ApplyOrCancelWidget> pCurApplyOrCancelGui = FindCurrentApplyOrCancelGui())
    {
        pCurApplyOrCancelGui->ResetPosition();
    }

    //UiNotificationManager::Get()->MoveNotification();

    QMainWindow::moveEvent(pEvent);
}

void GmMainWindow::resizeEvent(QResizeEvent *event)
{
    QMainWindow::resizeEvent(event);

    ApplicationWindowEvent* pMainWindowEvent = dynamic_cast<ApplicationWindowEvent*>(this->GetMainWindowEvent());
    DBG_WARN_AND_RETURN_VOID_UNLESS(pMainWindowEvent, L"主窗口对象析构时获取应用程序事件对象失败。",L"GDMPLab",L"2024-03-30");
    if (pMainWindowEvent)
    {
        ApplicationWindowEventArgs ResizeEventArgs(ApplicationWindowEventType::Resize);
        pMainWindowEvent->Emit(&ResizeEventArgs);
    }
    //MainWindow尺寸变化时，需要刷新Ribbon页面
    m_pRibbonBar->UpdateRibbonControlStatus();
}


bool GmMainWindow::nativeEvent(const QByteArray & eventType, void * message, long * result)
{
    MSG *msg = (MSG *)message;

    if (msg->message == ID_ACTIVE_MAIN_WINDOW)
    {
        this->setWindowState((this->windowState() & ~Qt::WindowMinimized) | Qt::WindowActive);
        this->show();
        this->activateWindow();

        return true;
    }
    else
    {
        return false;
    }
}

void GmMainWindow::TileSubWindows()
{
    if (m_pMDIArea)
    {
        m_pMDIArea->tileSubWindows();
    }
}

void GmMainWindow::CascadeSubWindows()
{
    if (m_pMDIArea)
        m_pMDIArea->cascadeSubWindows();
}

bool GmMainWindow::GetMdiAreaDomain(int& posx, int& posy, int& width, int& height) const
{
    if(m_pMDIArea == nullptr)
        return false;

    QPoint pnt = mapToGlobal(m_pMDIArea->pos());
    posx = pnt.x();
    posy = pnt.y();
    width = m_pMDIArea->width();
    height = m_pMDIArea->height();
    return true;
}

gcmp::IPlatformUiRefreshedEvent* GmMainWindow::GetPlatformUiRefreshedEvent() const
{
    return const_cast<IPlatformUiRefreshedEvent*>(m_pPlatformUiRefreshedEvent.get());
}

IUiView * gcmp::GmMainWindow::CreateOrOpenUiView(int uiDocId, const ElementId & modelViewId, bool isModelViewShared, const std::wstring &tag)
{
    IUiDocumentViewManager* pUiDocumentViewManager = IUiDocumentViewManager::Get();
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pUiDocumentViewManager, L"pUiDocumentViewManager为空",L"GDMPLab",L"2024-03-30");
    IUiDocument* pUIDoc = pUiDocumentViewManager->GetUiDocumentByRuntimeId(uiDocId);
    DBG_WARN_AND_RETURN_UNLESS(pUIDoc != nullptr, nullptr, L"pUIDoc为空",L"GDMPLab",L"2024-03-30");
    IDocument* pDoc = pUIDoc->GetDbDocument();
    DBG_WARN_AND_RETURN_UNLESS(pDoc, nullptr, L"pDoc为空",L"GDMPLab",L"2024-03-30");
    IModelView* pModelView = quick_cast<IModelView>(pDoc->GetElement(modelViewId));
    DBG_WARN_AND_RETURN_UNLESS(pModelView != nullptr, nullptr, L"pModelView为空",L"GDMPLab",L"2024-03-30");
    // 如果该视图已经打开，则找到它
    IUiView* pViewToOpen = nullptr;
    GmSubFrame* pSubFrame = nullptr;
    QList<QMdiSubWindow *> pSubWindows = m_pMDIArea->subWindowList();

    if (!isModelViewShared)
    {
        for (auto itSubWindow = pSubWindows.begin(); itSubWindow != pSubWindows.end(); ++itSubWindow)
        {
            pSubFrame = (GmSubFrame*)(*itSubWindow);
            DBG_WARN_AND_CONTINUE_UNLESS(pSubFrame != nullptr, L"pGmSubFrame为空",L"GDMPLab",L"2024-03-30");
            if (IUiView* pGmView = pSubFrame->GetView())
            {
                if (modelViewId == pGmView->GetModelViewId() && pUIDoc == pGmView->GetUiDocument())
                {
                    pViewToOpen = pGmView;
                    break;
                }
            }
        }
    }

    if (pViewToOpen != nullptr)
    {
        pSubFrame->showMaximized();
        return pViewToOpen;
    }
    pSubFrame = NEW_AS_QT_CHILD(GmSubFrame, uiDocId, m_pMDIArea->viewport());
    pSubFrame->resize(m_pMDIArea->width(), m_pMDIArea->height());

    if (isModelViewShared)
    {
        pViewToOpen = pUiDocumentViewManager->CreateUiViewWithSharingModelView(uiDocId, modelViewId, tag, pSubFrame);
    }
    else
    {
        pViewToOpen = pUiDocumentViewManager->CreateUiViewWithoutSharingModelView(uiDocId, modelViewId, tag, pSubFrame);
    }
    DBG_WARN_AND_RETURN_UNLESS(pViewToOpen, nullptr, L"pViewToOpen为空",L"GDMPLab",L"2024-03-30");
    std::wstring docName = pDoc->GetName();
    pSubFrame->setWindowTitle(QString::fromStdWString(docName + L" - " + pModelView->GetBasicInformation()->GetName()));
    m_pMDIArea->addSubWindow(pSubFrame, Qt::SubWindow);
    m_pMDIArea->setActivationOrder(QMdiArea::ActivationHistoryOrder);

    pSubFrame->SetView(pViewToOpen);
    QObject::connect(pSubFrame, SIGNAL(NotifyCloseView(QMdiSubWindow *)), this, SLOT(OnUIViewClose(QMdiSubWindow *)));
    pSubFrame->showMaximized();

    return pViewToOpen;
}

UInt64 gcmp::GmMainWindow::GetMdiAreaId() const
{
    DBG_WARN_AND_RETURN_UNLESS(m_pMDIArea, 0, L"m_pMDIArea为空",L"GDMPLab",L"2024-03-30");
    return m_pMDIArea->winId(); 
}

void gcmp::GmMainWindow::ActivateWindow()
{
    QMainWindow::activateWindow();
}

void GmMainWindow::UpdateControlStatus()
{
    if (DebugMessageMgr::GetDebugMessageMgr()->IsShowingDebugWarn())
        return;

    if (m_pRibbonBar)
    {
        m_pRibbonBar->UpdateRibbonControlStatus();
    }
    if (m_pStatusBar)
    {
        m_pStatusBar->UpdateControlStatus();
    }
    IUiManager* pUiMgr = IUiManager::Get();
    DBG_WARN_AND_RETURN_VOID_UNLESS(pUiMgr, L"pUiMgr为空！",L"GDMPLab",L"2024-03-30");
    IDockManager* pDockManager = pUiMgr->GetDockManager();
    if (pDockManager && IUiDocumentViewManager::Get()->GetCurrentUiDocument())
    {
        pDockManager->UpdateAllDockStatus();
    }
    if (PlatformUiRefreshedEvent* pEvent = dynamic_cast<PlatformUiRefreshedEvent*>(m_pPlatformUiRefreshedEvent.get()))
    {
        PlatformUiRefreshedEventArgs args;
        pEvent->Emit(&args);
    }
}

bool GmMainWindow::SetMainWindowHelper(OwnerPtr<IMainWndHelper> pMainWindowHelper)
{
    m_pMainWindowHelper = TransferOwnership(pMainWindowHelper);
    return true;
}

bool GmMainWindow::EnquiryDocumentBeforeClose(IUiDocument* pUIDoc)
{
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pUIDoc != nullptr, L"pUIDoc为空",L"GDMPLab",L"2024-03-30");
    IDocument* pDoc = pUIDoc->GetDbDocument();
    std::wstring docName;
    if (pDoc->IsChangedAfterPreviousSave())
    {
        IUiDocumentViewManager* pUiDocViewMgr = IUiDocumentViewManager::Get();
        DBG_WARN_AND_RETURN_FALSE_UNLESS(pUiDocViewMgr != nullptr, L"pUiDocViewMgr不能为null",L"GDMPLab",L"2024-03-30");
        bool isCanBeClose = pUiDocViewMgr->CanUiDocumentClose(pUIDoc->GetId());
        return isCanBeClose;
    }

    return true;
}

void GmMainWindow::closeAllSubWindowsAutomatically()
{
    // 设置标志，表示程序正在关闭
    SetApplicationIsClosing(true);

    QList<QMdiSubWindow *> pSubWindows = m_pMDIArea->subWindowList();
    for(auto it = pSubWindows.begin(); it != pSubWindows.end(); ++it)
    {
        GmSubFrame* pGmSubFrame = dynamic_cast<GmSubFrame*>(*it);
        DBG_WARN_AND_CONTINUE_UNLESS(pGmSubFrame != nullptr, L"子窗口指针为空是不可能的！",L"GDMPLab",L"2024-03-30");
        bool isAllowDocumentToBeClosed = true;
        pGmSubFrame->CloseByMainFrameAutomatically();
    }
    pSubWindows.clear();
}

void GmMainWindow::ActivateSubWindow( QMdiArea* mDIArea,QMdiSubWindow *subWindow )
{
    DBG_WARN_AND_RETURN_VOID_UNLESS(mDIArea != nullptr, L"mDIArea为空",L"GDMPLab",L"2024-03-30");
    DBG_WARN_AND_RETURN_VOID_UNLESS(subWindow != nullptr, L"subWindow为空",L"GDMPLab",L"2024-03-30");

    mDIArea->setActiveSubWindow(subWindow);
    OnSubWindowActivated(subWindow,true);
}

void GmMainWindow::OnSubWindowActivated(QMdiSubWindow* pMdiSubWindow,bool bActivatedProgrammactially)
{
    if (IsSubFrameAutoClosed())
    {
        bActivatedProgrammactially = true;
    }
    
    bool isActived = true;
    // When pMdiSubWindow is 0, QMdiArea has just deactivated its last active window, and there are no active windows on the workspace.
    if (pMdiSubWindow == nullptr)
    {
        if (m_pMainWindowHelper)
        {
            setWindowTitle(QString::fromStdWString(m_pMainWindowHelper->ComputeWindowTitle(FilePathManager::Get()->GetGitRevisionFilePath().GetFullPath())));
        }
    }
    else
    {
        FYI(L"OnSubWindowActivated pMdiSubWindow is not null");

        if (GmSubFrame* pSubFrame = dynamic_cast<GmSubFrame*>(pMdiSubWindow))
        {
            isActived = pSubFrame->OnWindowActivated();
        }     
    }

    // 程序要是正在退出，就不用刷新界面了
    if (!GetApplicationIsClosing() && isActived)
    {
        UpdateControlStatus();
    }
}

// 处理UIView关闭消息
void GmMainWindow::OnUIViewClose(QMdiSubWindow * pMdiSubWindow)
{
    if (pMdiSubWindow == nullptr)
        return;

    IUiDocumentViewManager* pUiDocumentViewManager = IUiDocumentViewManager::Get();
    DBG_WARN_AND_RETURN_VOID_UNLESS(pUiDocumentViewManager, L"pUiDocumentViewManager为空",L"GDMPLab",L"2024-03-30");

    IUiView* pUIView = dynamic_cast<GmSubFrame*>(pMdiSubWindow)->GetView();
    
    // 检查是否关闭所有浮动面板。
    if (pUiDocumentViewManager->GetAllUiDocuments().empty())
    {
        {
            //TODO-XY: 新的属性面板管理器更新
            IUiManager *pUiManager = IUiManager::Get();
            DBG_WARN_AND_RETURN_VOID_UNLESS(pUiManager, L"pUiManager为空",L"GDMPLab",L"2024-03-30");
            IDockManager* pDockManager = pUiManager->GetDockManager();
            if (pDockManager)
            {
                pDockManager->HideAllDockPane();
            }
        }
    }
}

GmSubFrame* GmMainWindow::GetCorrespondingSubFrame(IUiView* pUiView) const
{
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pUiView, L"pUiView为空",L"GDMPLab",L"2024-03-30");
    if (m_pMDIArea)
    {
        QList<QMdiSubWindow *> pSubWindows = m_pMDIArea->subWindowList();
        for (auto it = pSubWindows.begin(); it != pSubWindows.end(); ++it)
        {
            GmSubFrame* pGmSubFrame = dynamic_cast<GmSubFrame*>(*it);
            if (IUiView* pGmView = pGmSubFrame->GetView())
            {
                //维护当前UIView
                if (pGmView->GetId() == pUiView->GetId())
                {
                    return pGmSubFrame;
                }
            }
        }
    }

    return nullptr;
}

//////////////////////////////////////////////////////////////////////////
std::shared_ptr<ApplyOrCancelWidget> GmMainWindow::FindCurrentApplyOrCancelGui() const
{
    IUiDocumentViewManager* pUiDocumentViewManager = IUiDocumentViewManager::Get();
    DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pUiDocumentViewManager, L"pUiDocumentViewManager为空",L"GDMPLab",L"2024-03-30");
    IUiDocument * pCurUIDoc = pUiDocumentViewManager->GetCurrentUiDocument();
    if (!pCurUIDoc)
    {
        return nullptr;
    }

    const int curUIDocID = pCurUIDoc->GetId();
    std::shared_ptr<ApplyOrCancelWidget> pCurApplyOrCancelGui = nullptr;
    FOR_EACH(pApplyOrCancelGui, m_applyOrCancelGuis)
    {
        if (pApplyOrCancelGui && pApplyOrCancelGui->GetUIDocID() == curUIDocID)
        {
            pCurApplyOrCancelGui = pApplyOrCancelGui;
            break;
        }
    }
    return pCurApplyOrCancelGui;
}

void GmMainWindow::ShowApplyOrCancelGui(const std::wstring& hint, const std::wstring& applyCmd, const std::wstring& cancelCmd)
{
    IUiDocumentViewManager* pUiDocumentViewManager = IUiDocumentViewManager::Get();
    DBG_WARN_AND_RETURN_VOID_UNLESS(pUiDocumentViewManager, L"pUiDocumentViewManager为空",L"GDMPLab",L"2024-03-30");

    IUiDocument * pCurUIDoc = pUiDocumentViewManager->GetCurrentUiDocument();
    DBG_WARN_AND_RETURN_VOID_UNLESS(pCurUIDoc, L"pCurUIDoc为空？",L"GDMPLab",L"2024-03-30");
    const int curUIDocID = pCurUIDoc->GetId();

    // 只显示当前UIDoc的ApplyCancelGui，属于其它UIDoc的隐藏
    std::shared_ptr<ApplyOrCancelWidget> pCurApplyOrCancelGui = nullptr;
    FOR_EACH(pApplyOrCancelGui, m_applyOrCancelGuis)
    {
        if (!pApplyOrCancelGui)
        {
            continue;
        }
        if (pApplyOrCancelGui->GetUIDocID() == curUIDocID)
        {
            pCurApplyOrCancelGui = pApplyOrCancelGui;
        }
        else
        {
            // 不是当前UIDoc的隐藏掉
            pApplyOrCancelGui->ForceHide();
        }
    }
    // UIDoc第一次使用ApplyCancelGui，先创建
    if (!pCurApplyOrCancelGui)
    {
        // parent是MDIArea而不能是this，不然ApplyOrCancelWidget会浮在Ribbon、DocWidget等控件上面
        std::shared_ptr<ApplyOrCancelWidget> pCurApplyOrCancelGuiNew = NEW_AS_SHARED_PTR(ApplyOrCancelWidget, m_pMDIArea->viewport(), curUIDocID);
        pCurApplyOrCancelGui = pCurApplyOrCancelGuiNew;
        m_applyOrCancelGuis.push_back(pCurApplyOrCancelGui);
    }

    DBG_WARN_AND_RETURN_VOID_UNLESS(pCurApplyOrCancelGui, L"pCurApplyOrCancelGui一定不为空",L"GDMPLab",L"2024-03-30");
    bool isChange = pCurApplyOrCancelGui->PushCommandPair(hint, applyCmd, cancelCmd);
    if (isChange)
    {
        IUiView* pCurrentView = IUiDocumentViewManager::Get()->GetCurrentUiView();

        DBG_WARN_AND_RETURN_VOID_UNLESS(m_opUiViewLayoutManager, L"m_opUiViewLayoutManager不能为空!",L"GDMPLab",L"2024-03-30");
        UiViewLayoutEvent* pViewLayoutEvent = dynamic_cast<UiViewLayoutEvent*>(m_opUiViewLayoutManager->GetUiViewLayoutEvent());
        DBG_WARN_AND_RETURN_VOID_UNLESS(pViewLayoutEvent, L"pViewLayoutEvent不能为空!",L"GDMPLab",L"2024-03-30");
        pViewLayoutEvent->SetSender(pCurrentView);
        WId widgetId = dynamic_cast<ApplyOrCancelWidget*>(pCurApplyOrCancelGui.get())->winId();
        UiViewLayoutEventArgs Args(UiViewLayoutEventType::ApplyOrCancelWidgetShow, widgetId, pCurrentView);
        pViewLayoutEvent->Emit(&Args);
    }
}

void gcmp::GmMainWindow::HideApplyOrCancelGui()
{
    OnApplyOrCancelProcessed();
}

void GmMainWindow::OnApplyOrCancelProcessed()
{

    if (std::shared_ptr<ApplyOrCancelWidget> pCurApplyOrCancel = FindCurrentApplyOrCancelGui())
    {
        IUiView* pCurrentView = IUiDocumentViewManager::Get()->GetCurrentUiView();

        UiViewLayoutManager *pViewLayoutManager = UiViewLayoutManager::Get();
        DBG_WARN_AND_RETURN_VOID_UNLESS(pViewLayoutManager, L"pViewLayoutManager不能为空!",L"GDMPLab",L"2024-03-30");

        UiViewLayoutEvent* pViewLayoutEvent = dynamic_cast<UiViewLayoutEvent*>(pViewLayoutManager->GetUiViewLayoutEvent());
        DBG_WARN_AND_RETURN_VOID_UNLESS(pViewLayoutEvent, L"pViewLayoutEvent不能为空!",L"GDMPLab",L"2024-03-30");
        pViewLayoutEvent->SetSender(pCurrentView);

        WId widgetId = dynamic_cast<ApplyOrCancelWidget*>(pCurApplyOrCancel.get())->winId();
        UiViewLayoutEventArgs Args(UiViewLayoutEventType::ApplyOrCancelWidgetHide, widgetId, pCurrentView);
        pViewLayoutEvent->Emit(&Args);

        pCurApplyOrCancel->PopCommandPair();
    }
}

void GmMainWindow::ResetApplyOrCancelGuiPosition()
{
    if (std::shared_ptr<ApplyOrCancelWidget> pCurApplyOrCancel = FindCurrentApplyOrCancelGui())
    {
        pCurApplyOrCancel->ResetPosition();
    }
}

void GmMainWindow::DeleteApplyOrCancelGui(int uiDocId)
{
    for (auto iter = m_applyOrCancelGuis.begin(); iter != m_applyOrCancelGuis.end(); ++iter)
    {
        if ((*iter)->GetUIDocID() == uiDocId)
        {
            (*iter)->ForceHide();
            break;
        }
    }
}

bool GmMainWindow::focusNextPrevChild(bool next)
{
    return true;
}

bool GmMainWindow::Initialize()
{
    IApplicationConfig* pConfig = IApplication::Get()->GetConfig();
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pConfig, L"pConfig is null",L"GDMPLab",L"2024-03-30");

    // 设置窗口icon
    std::wstring icon = FilePath::GetAbsolutePath(pConfig->GetApplicationIconPath(), FileSystem::GetExeDirPath());
    setWindowIcon(QIcon(QString::fromStdWString(icon)));

    IApplication* pApplication = IApplication::Get();
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pApplication, L"pApplication为空？",L"GDMPLab",L"2024-03-30");
    std::vector<std::wstring> vecName = pApplication->GetCommandLineArgs();
    DBG_WARN_AND_RETURN_FALSE_UNLESS(vecName.size() > 0, L"无命令行参数？",L"GDMPLab",L"2024-03-30");
    std::wstring fullName = vecName[0];
    FilePath filePath(fullName);
    std::wstring appName = filePath.GetFileNameWithoutExtension();

    ISplashScreen* pSplashScreen = pApplication->GetSplashScreen();
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pSplashScreen, L"pSplashScreen is null",L"GDMPLab",L"2024-03-30");

    // 主窗口显示前发送事件
    ApplicationWindowEvent* pMainWindowEvent = dynamic_cast<ApplicationWindowEvent*>(GetMainWindowEvent());
    DBG_WARN_AND_RETURN_FALSE_UNLESS(pMainWindowEvent, L"应用程序开始执行时获取主窗口事件对象失败。",L"GDMPLab",L"2024-03-30");

    {
        ApplicationWindowEventArgs eventArgs(ApplicationWindowEventType::PreFirstShow);
        pMainWindowEvent->Emit(&eventArgs);
    }

    if ((pSplashScreen) && (L"AppComponentEditor" != appName))
    {
        pSplashScreen->ShowMessage(GBMP_TR(L"正在初始化状态栏，请稍后..."));
        pSplashScreen->SetProgress(90);
    }

    if ((pSplashScreen) && (L"AppComponentEditor" != appName))
    {
        pSplashScreen->ShowMessage(GBMP_TR(L"正在更新控件状态，请稍后..."));
        pSplashScreen->SetProgress(99);
        DBG_WARN_UNLESS(99 == pSplashScreen->GetProgress(), L"进度和设置的值不一致",L"GDMPLab",L"2024-03-30");
        //pSplashScreen->Finish(pMainWindow);
    }

    UpdateControlStatus();
    ShowMaximized();

    // 为所有Event Hanlder发送事件
    {
        ApplicationWindowEventArgs mainWindowEventArgs(ApplicationWindowEventType::Prepared);
        pMainWindowEvent->Emit(&mainWindowEventArgs);
    }

    return true;
}
